/**
 * 创建装饰器
 */
function d(target: any, key: string) {
  // any 是不确定是静态属性还是普通属性
  console.log(target, key);
  console.log(target === A.prototype);
}
/**
 * 创建类
 * 属性装饰器也是一个函数，这个函数至少需要两个参数
 * 参数1：如果是一个实例属性，是类的原型；如果是静态属性，参数为类本身
 * 参数2：字符串类型，表示属性名
 */
class A {
  @d
  prop1: string;
  @d
  static prop2: string;
}

/**
 * 属性装饰器的工厂模式
 */
function DD(str: string) {
  console.log("属性装饰器的工厂模式", str);
  return function (target: any, key: string) {
    console.log(target, key);
    target[key] = str; // 如果是实例属性，这里的Str会被赋值到原型属性上。AA.prototype
    // 如果是静态属性，这里的str给到类本身 AA
  };
}
class AA {
  @DD("hello")
  prop1: string;
  @DD("world")
  static prop2: string;
}
const aa = new AA();
console.log(AA.prototype, AA);
/**
 * 实现装饰器 将值赋值到实例对象的属性
 */
function DDD(str: string) {
  return function (target: any, key: string) {
    if (!target.__props) {
      target.__props = {};
    }
    if (!target.__initProperties)
      target.__initProperties = function () {
        for (let prop in target.__props) {
          this[prop] = target.__props[prop];
        }
        target.__props = {};
      };
    target.__props[key] = str;
  };
}
class AAA {
  @DDD("hello")
  prop1: string;
  @DDD("world")
  prop2: string;
  constructor() {
    // 判断有没有自己定义的函数
    if (typeof this["__initProperties"] === "function") {
      this["__initProperties"]();
    }
  }
}
const aaa = new AAA();
console.log(aaa.prop1 + " " + aaa.prop2);
export {};
